home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2002 #11
/
Amiga Plus CD - 2002 - No. 11.iso
/
Tools
/
Development
/
reportplus
/
source
/
f10.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-10-27
|
72KB
|
1,950 lines
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <dos/dosextens.h>
#include <dos/exall.h>
#include <dos/datetime.h>
#include <graphics/gfx.h>
#include <clib/alib_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/dos_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/exec_protos.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "rp.h"
#define ALL_REACTION_CLASSES
#include <reaction/reaction.h>
#define FILESMODE_BUILD 0
#define FILESMODE_COMPARE 1
#define VERSIONLENGTH 40
MODULE void updatefiles(void);
MODULE void stage1(void);
MODULE void files_work(void); // for stage1()
MODULE void stage2(void);
MODULE void dobuffer(ULONG whichpen); // for stage2()
MODULE void stopping(STRPTR status);
MODULE void files_updatelog(void);
MODULE void updateghosting(void);
MODULE void gadgetstate(ABOOL starting);
MODULE void AddFilesNode(struct List* ListPtr, STRPTR pathname, STRPTR datetime, STRPTR version, STRPTR size);
MODULE void FreeFilesNodes(struct List* ListPtr);
MODULE void addslash(void);
IMPORT ABOOL ram;
IMPORT SBYTE page;
IMPORT TEXT IOBuffer[LONGESTFIELD + 1],
aslresult[PATHNAMEFIELD + 1];
IMPORT ULONG increment;
IMPORT struct Screen* ScreenPtr;
IMPORT struct ExAllData* EADataPtr;
IMPORT struct Menu* MenuPtr;
IMPORT Object* WinObject[FUNCTIONS + 1];
IMPORT struct Library *ButtonBase,
*CheckBoxBase,
*ChooserBase,
*IconBase,
*LabelBase,
*LayoutBase,
*ListBrowserBase,
*StringBase,
*WindowBase;
IMPORT struct TextAttr Topaz8;
AGLOBAL struct Gadget* files_gadgets[GIDS_10 + 1];
AGLOBAL struct FilesStruct files =
{ TRUE, TRUE, TRUE, TRUE,
TRUE, TRUE, TRUE, TRUE,
0, FILESMODE_COMPARE,
"RAM:ReportPlus.log", "PROGDIR:ReportPlus.snapshot", "SYS:"
};
MODULE BOOL outerghost = FALSE,
innerghost = FALSE;
MODULE struct List DirList, // list of PathnameNodes (internal use)
FoundList, // list of FilesNodes
ResultList, // listbrowser list
EmptyResultList, // listbrowser list
SnapshotList; // list of FilesNodes (internal use)
MODULE ULONG filesfound,
status = STATUS_READY;
MODULE struct FilesNode
{ struct Node Node;
ABOOL matched;
TEXT datetime[18 + 1],
version[VERSIONLENGTH + 1],
size[13 + 1],
pathname[1];
};
MODULE BPTR TheHandle = NULL;
MODULE TEXT activedir[PATHNAMEFIELD + 1],
activefile[PATHNAMEFIELD + 1],
lockstring[PATHNAMEFIELD + 1],
liststring[7][PATHNAMEFIELD + 1];
#define COLUMN_PATHNAME 0
#define COLUMN_DATETIME 1
#define COLUMN_SIZE 2
#define COLUMN_VERSION 3
#define COLUMN_SSDATETIME 4
#define COLUMN_SSSIZE 5
#define COLUMN_SSVERSION 6
MODULE struct ColumnInfo ResultColumnInfo[] =
{ { 36, // WORD ci_Width
"Pathname", // STRPTR ci_Title
0, // ULONG ci_Flags
},
{ 10,
"Found Date/Time",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 7,
"Found Size",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 15,
"Found Version",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 10,
"Exp. Date/Time",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 7,
"Exp. Size",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 15,
"Expected Version",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ -1, (STRPTR) ~0, -1
} };
MODULE STRPTR ModeOptions[3] =
{ (STRPTR) "Make snapshot of base path",
(STRPTR) "Compare base path against snapshot",
NULL
};
MODULE struct
{ ULONG red, green, blue, pennumber;
} penn[5] =
{ {0x55555555, 0xFFFFFFFF, 0x55555555, -1}, // green (OK) .
{0xFFFFFFFF, 0x88888888, 0x00000000, -1}, // orange (changed) !
{0x55555555, 0xFFFFFFFF, 0xFFFFFFFF, -1}, // cyan (3rd-party) +
{0xFFFFFFFF, 0x44444444, 0x44444444, -1}, // red (missing) -
{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -1}, // white (built) n/a
};
// from rp.c
IMPORT SBYTE page;
IMPORT struct Window* MainWindowPtr;
IMPORT TEXT weekdaystring[LEN_DATSTRING],
datestring[LEN_DATSTRING],
timestring[LEN_DATSTRING];
AGLOBAL void files1(void)
{ struct Hook Hook10Struct;
updateghosting();
InitHook(&Hook10Struct, Hook10Func, NULL);
/* Create the window object. */
lockscreen();
if (!(WinObject[10] =
NewObject
(
WINDOW_GetClass(), NULL,
WA_PubScreen, ScreenPtr,
WA_ScreenTitle, "Report+",
WA_Title, "Report+: System Files Report",
WA_Activate, TRUE,
WA_DepthGadget, TRUE,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_SizeGadget, TRUE,
WA_IDCMP, IDCMP_RAWKEY,
WINDOW_IDCMPHook, &Hook10Struct,
WINDOW_IDCMPHookBits, IDCMP_RAWKEY,
WINDOW_MenuStrip, MenuPtr,
WINDOW_Position, WPOS_CENTERSCREEN,
WINDOW_ParentGroup, files_gadgets[GID_10_LY1] =
NewObject(LAYOUT_GetClass(), NULL,
// root-layout
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_DeferLayout, TRUE,
LAYOUT_AddChild, NewObject(LAYOUT_GetClass(), NULL,
// layout
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_NONE,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_LEFT,
LAYOUT_BevelStyle, BVS_NONE,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_LEFT,
LAYOUT_BevelStyle, BVS_FIELD,
LAYOUT_AddImage,
NewObject
( LABEL_GetClass(), NULL,
LABEL_Text, "Show:",
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB1] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB1,
GA_RelVerify, TRUE,
CHECKBOX_BackgroundPen, penn[0].pennumber,
GA_Text, "_OK (.)",
GA_Selected, (BOOL) files.show[0],
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB2] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB2,
GA_RelVerify, TRUE,
CHECKBOX_BackgroundPen, penn[1].pennumber,
GA_Text, "_Changed (!)",
GA_Selected, (BOOL) files.show[1],
TAG_END
),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB3] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB3,
GA_RelVerify, TRUE,
CHECKBOX_BackgroundPen, penn[2].pennumber,
GA_Text, "_3rd-party (+)",
GA_Selected, (BOOL) files.show[2],
TAG_END
),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB4] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB4,
GA_RelVerify, TRUE,
CHECKBOX_BackgroundPen, penn[3].pennumber,
GA_Text, "_Missing (-)",
GA_Selected, (BOOL) files.show[3],
TAG_END),
CHILD_WeightedHeight, 0,
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_LEFT,
LAYOUT_BevelStyle, BVS_FIELD,
LAYOUT_AddImage,
NewObject
( LABEL_GetClass(), NULL,
LABEL_Text, "Compare:",
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB8] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB8,
GA_RelVerify, TRUE,
GA_Text, "Si_zes",
GA_Selected, (BOOL) files.checksize,
GA_Disabled, outerghost,
TAG_END),
CHILD_WeightedWidth, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB6] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB6,
GA_RelVerify, TRUE,
GA_Text, "_Dates/times",
GA_Selected, (BOOL) files.checkdatetime,
GA_Disabled, outerghost,
TAG_END),
CHILD_WeightedWidth, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB5] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB5,
GA_RelVerify, TRUE,
GA_Text, "_Versions",
GA_Selected, (BOOL) files.checkversion,
GA_Disabled, outerghost,
TAG_END),
CHILD_WeightedWidth, 0,
TAG_END),
CHILD_WeightedHeight, 0,
TAG_END),
CHILD_WeightedWidth, 0,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_VertAlignment, LALIGN_TOP,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_NONE,
LAYOUT_ShrinkWrap, TRUE,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_FIELD,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_FIELD,
LAYOUT_ShrinkWrap, TRUE,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_TOP,
LAYOUT_HorizAlignment,LALIGN_LEFT,
LAYOUT_BevelStyle, BVS_NONE,
LAYOUT_AddImage,
NewObject
( LABEL_GetClass(), NULL,
LABEL_Text, "Mod_e:",
TAG_END),
CHILD_WeightedWidth, 0,
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_RA1] =
NewObject
( RADIOBUTTON_GetClass(),NULL,
GA_ID, GID_10_RA1,
GA_RelVerify, TRUE,
GA_Text, ModeOptions,
RADIOBUTTON_Selected, (WORD) files.mode,
TAG_END),
TAG_END),
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_NONE,
LAYOUT_ShrinkWrap, TRUE,
LAYOUT_AddImage,
NewObject
( LABEL_GetClass(), NULL,
LABEL_Text, "_Snapshot pathname:",
TAG_END),
CHILD_WeightedWidth, 0,
LAYOUT_AddChild, files_gadgets[GID_10_ST2] =
NewObject
( STRING_GetClass(),NULL,
GA_ID, GID_10_ST2,
GA_TabCycle, TRUE,
GA_RelVerify, TRUE,
STRINGA_TextVal, files.snapshot,
STRINGA_MaxChars, PATHNAMEFIELD,
STRINGA_MinVisible,10,
TAG_END),
CHILD_WeightedWidth, 100,
LAYOUT_AddChild, files_gadgets[GID_10_BU4] =
NewObject
( NULL, "button.gadget",
GA_ID, GID_10_BU4,
GA_RelVerify, TRUE,
BUTTON_AutoButton,BAG_POPFILE,
TAG_END),
CHILD_WeightedWidth, 0,
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_NONE,
LAYOUT_ShrinkWrap, TRUE,
LAYOUT_AddImage,
NewObject
( LABEL_GetClass(), NULL,
LABEL_Text, "_Base path:",
TAG_END),
CHILD_WeightedWidth, 0,
LAYOUT_AddChild, files_gadgets[GID_10_ST3] =
NewObject
( STRING_GetClass(),NULL,
GA_ID, GID_10_ST3,
GA_TabCycle, TRUE,
GA_RelVerify, TRUE,
STRINGA_TextVal, files.basepath,
STRINGA_MinVisible,10,
STRINGA_MaxChars, PATHNAMEFIELD,
TAG_END),
CHILD_WeightedWidth, 100,
LAYOUT_AddChild, files_gadgets[GID_10_BU5] =
NewObject
( NULL, "button.gadget",
GA_ID, GID_10_BU5,
GA_RelVerify, TRUE,
BUTTON_AutoButton,BAG_POPFILE,
TAG_END),
CHILD_WeightedWidth, 0,
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_FG1] =
NewObject
( FUELGAUGE_GetClass(), NULL,
GA_ID, GID_10_FG1,
GA_Text, "Ready.",
FUELGAUGE_Level, 0,
FUELGAUGE_Percent, FALSE,
FUELGAUGE_Justification,FGJ_CENTER,
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_NONE,
LAYOUT_AddChild, files_gadgets[GID_10_BU2] =
NewObject
( NULL, "button.gadget",
GA_ID, GID_10_BU2,
GA_RelVerify, TRUE,
GA_Text, "_Update",
TAG_END),
CHILD_WeightedWidth, 50,
LAYOUT_AddChild, files_gadgets[GID_10_BU3] =
NewObject
( NULL, "button.gadget",
GA_ID, GID_10_BU3,
GA_RelVerify, TRUE,
GA_Text, "Stop",
GA_Disabled, TRUE,
TAG_END),
CHILD_WeightedWidth, 50,
TAG_END),
CHILD_WeightedHeight, 0,
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment, LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_NONE,
LAYOUT_ShrinkWrap, TRUE,
LAYOUT_AddChild, files_gadgets[GID_10_CB7] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB7,
GA_RelVerify, TRUE,
GA_Text, "_Log to:",
GA_Selected, (BOOL) files.log,
GA_Disabled, outerghost,
TAG_END),
CHILD_WeightedWidth, 0,
LAYOUT_AddChild, files_gadgets[GID_10_ST1] =
NewObject
( STRING_GetClass(), NULL,
GA_ID, GID_10_ST1,
GA_TabCycle, TRUE,
GA_RelVerify, TRUE,
STRINGA_TextVal, files.logfile,
STRINGA_MinVisible, 10,
STRINGA_MaxChars, PATHNAMEFIELD,
GA_Disabled, innerghost,
TAG_END),
CHILD_WeightedWidth, 100,
LAYOUT_AddChild, files_gadgets[GID_10_BU1] =
NewObject
( NULL, "button.gadget",
GA_ID, GID_10_BU1,
GA_RelVerify, TRUE,
BUTTON_AutoButton,BAG_POPFILE,
GA_Disabled, innerghost,
TAG_END),
CHILD_WeightedWidth, 0,
TAG_END),
CHILD_WeightedHeight, 0,
TAG_END),
CHILD_WeightedHeight, 0,
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_LB1] =
NewObject
( LISTBROWSER_GetClass(), NULL,
GA_ID, GID_10_LB1,
GA_ReadOnly, TRUE,
GA_TextAttr, &Topaz8,
LISTBROWSER_Labels, (ULONG) &EmptyResultList,
LISTBROWSER_ColumnInfo, (ULONG) &ResultColumnInfo,
LISTBROWSER_ColumnTitles, TRUE,
LISTBROWSER_HorizontalProp,TRUE,
LISTBROWSER_VirtualWidth, 620 + 620 + 310,
LISTBROWSER_MinVisible, 6,
TAG_END),
CHILD_WeightedHeight, 100,
CHILD_MinHeight, 128,
TAG_END),
TAG_END
)))
{ rq("Can't create ReAction object(s)!");
}
unlockscreen();
openwindow();
ActivateLayoutGadget(files_gadgets[GID_10_LY1], MainWindowPtr, NULL, (Object) files_gadgets[GID_10_ST2]);
loop();
closewindow();
files_exit();
}
MODULE void updatefiles(void)
{ STRPTR stringptr;
/* Most gadgets are ghosted during the operation. Then their ghosting
status returns to normal (not necessarily unghosted).
0: Gadget handling.
1: Set up lists, do the directory examination.
(For each `source' directory in the `queue', before doing it
we check for a break. `Break opportunity 1'.)
At this point we have an empty DirList, and a full FoundList, and an
empty ResultList.
2: Create the ResultList.
(For each `source' file in the `queue', before doing it we
check for a break. `Break opportunity 2'.)
3: Show results.
DirList: an Exec list (PathnameNodes) of directories found, awaiting examination.
FoundList: an Exec list (FilesNodes) of files found, awaiting processing.
SnapshotList: an Exec list (FilesNodes) of files in the snapshot file.
ResultList: a listbrowser list of files found, for display.
Apparently the way strings work is that you get told an address where
the string is stored. This is apparently a pointer into system memory;
it doesn't need explicit allocation/deallocation by our appliprog. */
if (!(GetAttr
( STRINGA_TextVal, files_gadgets[GID_10_ST1], (ULONG *) &stringptr
)))
{ rq("Unsupported inquiry!"); // should never happen
}
strcpy(files.logfile, stringptr);
if (!(GetAttr
( STRINGA_TextVal, files_gadgets[GID_10_ST2], (ULONG *) &stringptr
)))
{ rq("Unsupported inquiry!"); // should never happen
}
strcpy(files.snapshot, stringptr);
if (!(GetAttr
( STRINGA_TextVal, files_gadgets[GID_10_ST3], (ULONG *) &stringptr
)))
{ rq("Unsupported inquiry!"); // should never happen
}
strcpy(files.basepath, stringptr);
addslash();
gadgetstate(TRUE);
SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, 100,
FUELGAUGE_Level, 8,
GA_Text, "Reading from volume...",
TAG_END
); // we don't know how many files in advance...
SetGadgetAttrs
( files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
LISTBROWSER_Labels, NULL,
TAG_END
);
SetGadgetAttrs
( files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
LISTBROWSER_Labels, (ULONG) &EmptyResultList,
TAG_END
);
if ((ResultList.lh_Head)->ln_Succ) // if the list is non-empty
{ clearreactionlist(&ResultList);
}
filesfound = 0;
status = STATUS_BUSY;
stage1(); // calls stage2() itself if appropriate
status = STATUS_READY;
gadgetstate(FALSE);
SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, 100,
FUELGAUGE_Level, 0,
GA_Text, "Ready.",
TAG_END
);
SetGadgetAttrs
( files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
LISTBROWSER_Labels, NULL,
TAG_END
);
if ((ResultList.lh_Head)->ln_Succ) // if the list is non-empty
{ SetGadgetAttrs
( files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
LISTBROWSER_Labels, (ULONG) &ResultList,
TAG_END
);
} else
{ SetGadgetAttrs
( files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
LISTBROWSER_Labels, (ULONG) &EmptyResultList,
TAG_END
);
} }
MODULE void stage1(void)
{ struct PathnameNode* PathnameNodePtr;
// Initialize lists
NewList(&FoundList);
NewList(&DirList);
NewList(&ResultList);
NewList(&SnapshotList);
AddPathnameNode(&DirList, "");
// Pop all the directories from the work stack, and send them one
// at a time to files_work() for processing.
while ((DirList.lh_Head)->ln_Succ) // while the list is non-empty
{ if (ra_checkbreak() == 1) // we don't yet support completely quitting
{ status = STATUS_STOPPING;
stopping("Stopping...");
FreePathnameNodes(&DirList);
FreeFilesNodes(&FoundList);
return;
}
/* detach a node from the DirList, copy its path to activedir,
free the node, and then call files_work(). */
if (!(PathnameNodePtr = (struct PathnameNode *) RemTail(&DirList)))
{ rq("RemTail() failed (list is empty!)"); // this should never happen
}
strcpy(activedir, PathnameNodePtr->pathname);
FreeMem(PathnameNodePtr, sizeof(struct PathnameNode));
files_work(); // service routine
}
/* Now we have a list of all relevant files.
DirList will be empty.
FoundList will be 'full' (unless the user aborted, or nothing was found).
ResultList will be empty.
SnapshotList will be empty. */
stage2();
}
MODULE void stage2(void)
{ ABOOL matched;
ULONG filesdone = 0,
i, j, sizeval,
length;
struct FilesNode *FoundNodePtr,
*SnapshotNodePtr;
TEXT filename[PATHNAMEFIELD + 1],
pathname[PATHNAMEFIELD + 1],
datetime[18 + 1],
version[VLONGFIELD + 1],
size[13 + 1];
struct FileInfoBlock* FIBPtr;
STRPTR MemoryPtr;
/* We now have the list of all files found.
*1: Check versions of found files.
2: Read the snapshot file into memory.
3: Parse the snapshot file into a list of SnapshotNodes.
4: Open logfile and write logfile header.
*5: Check each found node against each snapshot node.
6: Decide missing files.
* means the operation can be aborted at this point.
1. Check versions of found files. ------------------------------------- */
if (files.mode == FILESMODE_BUILD || files.checkversion)
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, 100,
FUELGAUGE_Level, 16,
GA_Text, "Checking versions...",
TAG_END
);
if ((FoundList.lh_Head)->ln_Succ) // if the list is non-empty
{ for
( FoundNodePtr = FoundList.lh_Head;
FoundNodePtr->Node.ln_Succ;
FoundNodePtr = FoundNodePtr->Node.ln_Succ
)
{ if (ra_checkbreak() == 1)
{ status = STATUS_STOPPING;
stopping("Stopping...");
FreeFilesNodes(&FoundList);
return;
}
// check that file is not an icon
length = strlen(FoundNodePtr->pathname);
if (length < 5 || stricmp(&(FoundNodePtr->pathname[length - 5]), ".info"))
{ strcpy(pathname, files.basepath);
if (!(AddPart(pathname, FoundNodePtr->pathname, PATHNAMEFIELD)))
{ rq("AddPart() failed!");
}
getversion(pathname, version);
if (strlen(version) > VERSIONLENGTH)
{ version[VERSIONLENGTH - 3] =
version[VERSIONLENGTH - 2] =
version[VERSIONLENGTH - 1] = '.';
version[VERSIONLENGTH ] = 0;
}
strcpy(FoundNodePtr->version, version);
} else
{ strcpy(FoundNodePtr->version, "n/a");
} } } }
// 2. Read the snapshot file into memory. --------------------------------
if (files.mode == FILESMODE_BUILD)
{ if (!(TheHandle = (BPTR) Open(files.snapshot, MODE_NEWFILE)))
{ rq("Can't open snapshot file for writing!");
} }
else
{ assert(files.mode == FILESMODE_COMPARE);
SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, 100,
FUELGAUGE_Level, 24,
GA_Text, "Reading snapshot file...",
TAG_END
);
if (!(TheHandle = (BPTR) Lock(files.snapshot, ACCESS_READ)))
{ rq("Can't lock snapshot file!");
}
if (!(FIBPtr = AllocDosObject(DOS_FIB, NULL)))
{ UnLock(TheHandle);
TheHandle = NULL;
rq("Can't allocate DOS object!");
}
if (!(Examine(TheHandle, FIBPtr)))
{ FreeDosObject(DOS_FIB, FIBPtr);
FIBPtr = NULL;
UnLock(TheHandle);
TheHandle = NULL;
rq("Can't examine snapshot file!");
}
sizeval = FIBPtr->fib_Size;
comma(sizeval, size);
stcl_d(size, sizeval);
FreeDosObject(DOS_FIB, FIBPtr);
// FIBPtr = NULL;
UnLock(TheHandle);
TheHandle = NULL;
// Open the snapshot file, read it into memory, then close it.
if (!(TheHandle = (BPTR) Open(files.snapshot, MODE_OLDFILE)))
{ rq("Can't open snapshot file for reading!");
}
if (!(MemoryPtr = AllocVec(sizeval, NULL)))
{ rq("Out of memory!");
}
if (Read(TheHandle, MemoryPtr, sizeval) != sizeval)
{ rq("Can't read from snapshot file!");
}
Close(TheHandle);
TheHandle = NULL;
// 3. Parse the snapshot file into a list of SnapshotNodes. --------------
i = 0;
do
{ j = 0;
while (*(MemoryPtr + i) != LF)
{ pathname[j] = *(MemoryPtr + i);
i++;
j++;
}
pathname[j] = 0;
i++;
j = 0;
while (*(MemoryPtr + i) != LF)
{ datetime[j] = *(MemoryPtr + i);
i++;
j++;
}
datetime[j] = 0;
i++;
j = 0;
while (*(MemoryPtr + i) != LF)
{ version[j] = *(MemoryPtr + i);
i++;
j++;
}
version[j] = 0;
i++;
j = 0;
while (*(MemoryPtr + i) != LF)
{ size[j] = *(MemoryPtr + i);
i++;
j++;
}
size[j] = 0;
i++;
AddFilesNode(&SnapshotList, pathname, datetime, version, size);
} while (i < sizeval);
FreeVec(MemoryPtr);
// 4. Open logfile and write logfile header. -----------------------------
if (files.log)
{ if (!(TheHandle = (BPTR) Open(files.logfile, MODE_READWRITE)))
{ rq("Can't open logfile for appending!");
}
Seek(TheHandle, 0, OFFSET_END);
strcpy(IOBuffer, files.basepath);
strcat(IOBuffer, " files as at ");
getdate();
strcat(IOBuffer, timestring);
strcat(IOBuffer, " on ");
strcat(IOBuffer, weekdaystring);
strcat(IOBuffer, " ");
strcat(IOBuffer, datestring);
strcat(IOBuffer, ":\n\n");
if (Write(TheHandle, IOBuffer, strlen(IOBuffer)) != strlen(IOBuffer))
{ rq("Can't append to logfile!");
} } }
/* 5. Check each found node against each snapshot node. ------------------
We go through FoundList destructively, ie. freeing each node after we
have used it.
For each file found, we check it against each snapshot node. If it doesn't
match any, it's third-party. */
if (files.mode == FILESMODE_COMPARE)
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, filesfound * 3,
FUELGAUGE_Level, filesfound,
GA_Text, "Comparing...",
TAG_END
);
} else
{ assert(files.mode == FILESMODE_BUILD);
SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, filesfound * 3,
FUELGAUGE_Level, filesfound,
GA_Text, "Writing snapshot file...",
TAG_END
);
}
while ((FoundList.lh_Head)->ln_Succ) // while the list is non-empty
{ if (ra_checkbreak() == 1)
{ status = STATUS_STOPPING;
stopping("Stopping...");
if (files.mode == FILESMODE_BUILD || files.log)
{ strcpy(IOBuffer, "Aborted by user!");
if (Write(TheHandle, IOBuffer, strlen(IOBuffer)) != strlen(IOBuffer))
{ if (files.mode == FILESMODE_COMPARE)
{ rq("Can't append to logfile!");
} else
{ assert(files.mode == FILESMODE_BUILD);
rq("Can't write to snapshot file!");
} }
Close(TheHandle); // Close() doesn't return an error code
TheHandle = NULL;
}
FreeFilesNodes(&FoundList);
FreeFilesNodes(&SnapshotList);
return;
}
assert(status != STATUS_STOPPING);
if (!(filesdone % 20))
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Level, filesfound + filesdone,
TAG_END
);
}
filesdone++;
if (!(FoundNodePtr = (struct FilesNode *) RemTail(&FoundList)))
{ rq("RemTail() failed (list is empty!)"); // should never happen
}
strcpy(activefile, FoundNodePtr->pathname);
strcpy(datetime, FoundNodePtr->datetime);
strcpy(version, FoundNodePtr->version );
strcpy(size, FoundNodePtr->size );
FreeVec(FoundNodePtr);
// FilesNodePtr = NULL;
strcpy(filename, files.basepath);
strcat(filename, activefile);
if (files.mode == FILESMODE_BUILD)
{ strcpy(liststring[COLUMN_PATHNAME], " ");
strcat(liststring[COLUMN_PATHNAME], activefile);
strcpy(liststring[COLUMN_DATETIME], datetime);
strcpy(liststring[COLUMN_SIZE ], size);
strcpy(liststring[COLUMN_VERSION ], version);
strcpy(liststring[COLUMN_SSDATETIME], "n/a");
strcpy(liststring[COLUMN_SSSIZE ], "n/a");
strcpy(liststring[COLUMN_SSVERSION], "n/a");
dobuffer(4);
} else
{ // now we have removed the file from the list, and copied its
// name into activefile. Now we check it against each system
// file.
matched = FALSE;
if ((SnapshotList.lh_Head)->ln_Succ) // if the list is non-empty
{ for
( SnapshotNodePtr = SnapshotList.lh_Head;
SnapshotNodePtr->Node.ln_Succ;
SnapshotNodePtr = SnapshotNodePtr->Node.ln_Succ
)
{ if (!matched && !(stricmp(activefile, SnapshotNodePtr->pathname)))
{ // we have a match
matched = TRUE;
SnapshotNodePtr->matched = (ABOOL) TRUE;
if (files.checkdatetime)
{ strcpy(liststring[COLUMN_DATETIME], datetime);
strcpy(liststring[COLUMN_SSDATETIME], SnapshotNodePtr->datetime);
} else
{ strcpy(liststring[COLUMN_DATETIME], "n/a");
strcpy(liststring[COLUMN_SSDATETIME], "n/a");
}
if (files.checksize)
{ strcpy(liststring[COLUMN_SIZE ], size);
strcpy(liststring[COLUMN_SSSIZE], SnapshotNodePtr->size);
} else
{ strcpy(liststring[COLUMN_SIZE ], "n/a");
strcpy(liststring[COLUMN_SSSIZE], "n/a");
}
if (files.checkversion)
{ strcpy(liststring[COLUMN_VERSION], version);
strcpy(liststring[COLUMN_SSVERSION], SnapshotNodePtr->version);
} else
{ strcpy(liststring[COLUMN_VERSION ], "n/a");
strcpy(liststring[COLUMN_SSVERSION], "n/a");
}
if
( (files.checkdatetime && strcmp(SnapshotNodePtr->datetime, liststring[COLUMN_DATETIME]))
|| (files.checkversion && strcmp(SnapshotNodePtr->version, liststring[COLUMN_VERSION ]))
|| (files.checksize && strcmp(SnapshotNodePtr->size, liststring[COLUMN_SIZE ]))
)
{ strcpy(liststring[COLUMN_PATHNAME], "!");
strcat(liststring[COLUMN_PATHNAME], activefile);
if (files.show[1])
{ dobuffer(1);
} }
else
{ strcpy(liststring[COLUMN_PATHNAME], ".");
strcat(liststring[COLUMN_PATHNAME], activefile);
if (files.show[0])
{ dobuffer(0);
} }
break;
} } }
if (files.show[2] && !matched) // third-party
{ strcpy(liststring[COLUMN_PATHNAME], "+");
strcat(liststring[COLUMN_PATHNAME], activefile);
if (files.checkdatetime)
{ strcpy(liststring[COLUMN_DATETIME], datetime);
} else
{ strcpy(liststring[COLUMN_DATETIME], "?");
}
if (files.checkversion)
{ strcpy(liststring[COLUMN_VERSION], version);
} else
{ strcpy(liststring[COLUMN_VERSION], "?");
}
if (files.checksize)
{ strcpy(liststring[COLUMN_SIZE], size);
} else
{ strcpy(liststring[COLUMN_SIZE], "?");
}
strcpy(liststring[COLUMN_SSDATETIME], "n/a");
strcpy(liststring[COLUMN_SSVERSION ], "n/a");
strcpy(liststring[COLUMN_SSSIZE ], "n/a");
dobuffer(2);
} } }
/* 6. Decide missing files. ----------------------------------------------
Missing files can't be determined until we have looked through all the
found files. We go through the snapshot list looking at the `matched'
member variable. */
if (files.mode == FILESMODE_COMPARE)
{ // missing files
if (status == STATUS_BUSY && files.show[3])
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, 100,
FUELGAUGE_Level, 83,
GA_Text, "Deciding missing...",
TAG_END
);
if ((SnapshotList.lh_Head)->ln_Succ) // if the list is non-empty
{ for
( SnapshotNodePtr = SnapshotList.lh_Head;
SnapshotNodePtr->Node.ln_Succ;
SnapshotNodePtr = SnapshotNodePtr->Node.ln_Succ
)
{ if (!(SnapshotNodePtr->matched))
{ strcpy(liststring[COLUMN_PATHNAME], "-");
strcat(liststring[COLUMN_PATHNAME], SnapshotNodePtr->pathname);
strcpy(liststring[COLUMN_VERSION ], "n/a");
strcpy(liststring[COLUMN_DATETIME], "n/a");
strcpy(liststring[COLUMN_SIZE ], "n/a");
if (files.checkdatetime)
{ strcpy(liststring[COLUMN_SSDATETIME], SnapshotNodePtr->datetime);
} else
{ strcpy(liststring[COLUMN_SSDATETIME], "n/a");
}
if (files.checkversion)
{ strcpy(liststring[COLUMN_SSVERSION], SnapshotNodePtr->version);
} else
{ strcpy(liststring[COLUMN_SSVERSION], "n/a");
}
if (files.checksize)
{ strcpy(liststring[COLUMN_SSSIZE], SnapshotNodePtr->size);
} else
{ strcpy(liststring[COLUMN_SSSIZE], "n/a");
}
dobuffer(3);
} } } } }
if (TheHandle)
{ Close(TheHandle); // Close() doesn't return an error code
TheHandle = NULL;
} }
MODULE void files_work(void)
{ BOOL more; // BOOL, not ABOOL
BPTR DirHandle; // = NULL;
LONG ed;
struct ExAllControl* eac; // = NULL;
struct ExAllData* ead;
struct DateTime DateTime;
ULONG baselength = strlen(files.basepath);
TEXT datetime[18 + 1],
size[13 + 1];
DateTime.dat_Format = FORMAT_CDN;
DateTime.dat_Flags = NULL;
DateTime.dat_StrDay = NULL;
DateTime.dat_StrDate = datestring;
DateTime.dat_StrTime = timestring;
/* Service routine for stage1(). Each call of this routine
handles one directory from the work stack. This routine is the one
that actually makes the DOS calls. It pushes any subdirectories
found onto the stack.
lockstring contains the pathname of the directory to examine
(with base path).
activedir contains the pathname of the directory to examine
(without base path).
activefile will contain the pathname of each file/dir found
(with base path). */
strcpy(lockstring, files.basepath);
strcat(lockstring, activedir);
if (!(DirHandle = (BPTR) Lock(lockstring, ACCESS_READ)))
{ // Printf("Can't lock %s!\n", lockstring);
rq("Can't lock directory!");
}
if (!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL)))
{ UnLock(DirHandle);
DirHandle = NULL;
rq("Can't allocate DOS object!");
}
if (files.mode == FILESMODE_BUILD || files.checkdatetime)
{ ed = ED_DATE; // we want name, type, size and date
} elif (files.checksize)
{ ed = ED_SIZE; // we want name, type and size
} else
{ ed = ED_TYPE; // we want name and type
}
eac->eac_LastKey = 0;
do
{ more = ExAll(DirHandle, (struct ExAllData *) EADataPtr, 4096, ed, eac);
if (!more && IoErr() != ERROR_NO_MORE_ENTRIES)
{ FreeDosObject(DOS_EXALLCONTROL, eac);
eac = NULL;
UnLock(DirHandle);
DirHandle = NULL;
rq("Can't examine path!"); /* ExAll() failed abnormally */
}
if (eac->eac_Entries == 0)
{ ; /* ExAll() failed normally with no entries */
continue; /* more is USUALLY zero */
}
ead = (struct ExAllData *) EADataPtr;
do
{ /* use ead here */
strcpy(activefile, lockstring);
if (!AddPart(activefile, ead->ed_Name, PATHNAMEFIELD))
{ FreeDosObject(DOS_EXALLCONTROL, eac);
eac = NULL;
UnLock(DirHandle);
DirHandle = NULL;
rq("Can't add filename/dirname to path!");
}
if (ead->ed_Type == 2)
// +2 is dir, +3 is softlink (not yet supported), -3 is file
{ AddPathnameNode(&DirList, &activefile[baselength]);
} elif (ead->ed_Type == -3) // if it's a file
{ if (files.mode == FILESMODE_BUILD || files.checkdatetime)
{ DateTime.dat_Stamp.ds_Days = ead->ed_Days;
DateTime.dat_Stamp.ds_Minute = ead->ed_Mins;
DateTime.dat_Stamp.ds_Tick = ead->ed_Ticks;
DateToStr(&DateTime);
strcpy(datetime, timestring);
strcat(datetime, " ");
strcat(datetime, datestring);
} else
{ strcpy(datetime, "n/a");
}
if (files.mode == FILESMODE_BUILD || files.checksize)
{ comma(ead->ed_Size, size);
} else
{ strcpy(size, "n/a");
}
AddFilesNode
( &FoundList,
&activefile[baselength],
datetime,
"",
size
);
filesfound++;
}
/* get next ead */
ead = ead->ed_Next;
} while(ead);
} while(more);
FreeDosObject(DOS_EXALLCONTROL, eac);
// eac = NULL;
UnLock(DirHandle);
// DirHandle = NULL;
}
MODULE void dobuffer(ULONG whichpen)
{ struct Node* ListBrowserNodePtr;
TEXT codestring[512 + 1], // codestrings are sometimes longer than 256 chacters
spaces[LONGFIELD + 1];
SLONG gap;
ULONG i;
/* Service routine for stage2(). */
if (!(ListBrowserNodePtr = AllocListBrowserNode
( 7, // columns,
LBNA_Column, 0,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, &liststring[0][1],
LBNA_Column, 1,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[1],
LBNA_Column, 2,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[2],
LBNA_Column, 3,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[3],
LBNA_Column, 4,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[4],
LBNA_Column, 5,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[5],
LBNA_Column, 6,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[6],
TAG_END)))
{ rq("Can't create ReAction listbrowser.gadget node(s)!");
}
AddTail(&ResultList, ListBrowserNodePtr); // AddTail() has no return code
if (files.mode == FILESMODE_BUILD)
{ strcpy(codestring, &liststring[COLUMN_PATHNAME][1]);
strcat(codestring, "\n");
strcat(codestring, liststring[COLUMN_DATETIME]);
strcat(codestring, "\n");
strcat(codestring, liststring[COLUMN_VERSION]);
strcat(codestring, "\n");
strcat(codestring, liststring[COLUMN_SIZE ]);
strcat(codestring, "\n");
if (Write(TheHandle, codestring, strlen(codestring)) != strlen(codestring))
{ rq("Can't write to snapshot file!");
} }
else
{ assert(files.mode == FILESMODE_COMPARE);
if (files.log)
{ strcpy(codestring, liststring[COLUMN_PATHNAME]);
if (strlen(liststring[COLUMN_PATHNAME]) >= 35)
{ strcat(codestring, "\n"
" "); // 36 spaces
} else
{ gap = 36 - strlen(liststring[COLUMN_PATHNAME]);
for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
}
if (!(strcmp(liststring[COLUMN_SIZE], "n/a")))
{ strcat(codestring, " n/a "); // 10 spaces
} else
{ strcat(codestring, liststring[COLUMN_SIZE ]);
gap = 14 - strlen(liststring[COLUMN_SIZE ]);
if (gap >= 1)
{ for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
} }
strcat(codestring, liststring[COLUMN_DATETIME]);
gap = 18 - strlen(liststring[COLUMN_DATETIME]);
if (gap >= 1)
{ for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
}
strcat(codestring, liststring[COLUMN_VERSION]);
strcat(codestring, "\n"
" "); // 36 spaces
if (!(strcmp(liststring[COLUMN_SSSIZE], "n/a")))
{ strcat(codestring, " n/a "); // 10 spaces
} else
{ strcat(codestring, liststring[COLUMN_SSSIZE ]);
gap = 14 - strlen(liststring[COLUMN_SSSIZE ]);
if (gap >= 1)
{ for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
} }
strcat(codestring, liststring[COLUMN_SSDATETIME]);
gap = 18 - strlen(liststring[COLUMN_SSDATETIME]);
if (gap >= 1)
{ for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
}
strcat(codestring, liststring[COLUMN_SSVERSION]);
strcat(codestring, "\n");
if (Write(TheHandle, codestring, strlen(codestring)) != strlen(codestring))
{ rq("Can't append to logfile!");
} } } }
AGLOBAL void files_init(void)
{ ULONG i;
struct Node* ListBrowserNodePtr;
lockscreen();
for (i = 0; i <= 4; i++)
{ penn[i].pennumber = FindColor
( ScreenPtr->ViewPort.ColorMap,
penn[i].red,
penn[i].green,
penn[i].blue,
-1
);
}
unlockscreen();
NewList(&DirList);
NewList(&FoundList);
NewList(&SnapshotList);
NewList(&ResultList);
NewList(&EmptyResultList);
/* Create a 7-column listbrowser list with only one node containing
only column tags. */
if (!(ListBrowserNodePtr = AllocListBrowserNode
( 7, // columns
/* LBNCA_ tags are those that apply to the specific column. */
LBNA_Column, 0,
LBNA_Column, 1,
LBNA_Column, 2,
LBNA_Column, 3,
LBNA_Column, 4,
LBNA_Column, 5,
LBNA_Column, 6,
TAG_END
)))
{ rq("Can't create ReAction listbrowser.gadget node(s)!");
}
AddTail(&EmptyResultList, ListBrowserNodePtr); // AddTail() has no return code
}
AGLOBAL void files_exit(void)
{ // The window should be closed before calling this.
if ((ResultList.lh_Head)->ln_Succ) // if the list is non-empty
{ clearreactionlist(&ResultList);
}
if ((DirList.lh_Head)->ln_Succ) // if the list is non-empty
{ FreePathnameNodes(&DirList);
}
if ((FoundList.lh_Head)->ln_Succ) // if the list is non-empty
{ FreeFilesNodes(&FoundList);
}
if ((SnapshotList.lh_Head)->ln_Succ) // if the list is non-empty
{ FreeFilesNodes(&SnapshotList);
}
if (TheHandle)
{ Close(TheHandle); // Close() doesn't return an error code
TheHandle = NULL;
}
}
AGLOBAL void files_die(void)
{ ULONG i;
if ((EmptyResultList.lh_Head)->ln_Succ) // if the list is non-empty
{ clearreactionlist(&EmptyResultList);
}
IOBuffer[23] = (UBYTE) files.log;
for (i = 0; i <= 3; i++)
{ IOBuffer[i + 8] = (UBYTE) files.show[i];
}
IOBuffer[7] = (UBYTE) files.checkversion;
IOBuffer[12] = (UBYTE) files.checkdatetime;
IOBuffer[13] = (UBYTE) files.mode;
IOBuffer[14] = (UBYTE) files.checksize;
}
AGLOBAL void files_config(void)
{ UBYTE i;
files.log = (ULONG) IOBuffer[23];
for (i = 0; i <= 3; i++)
{ files.show[i] = (ULONG) IOBuffer[i + 8];
}
files.checkversion = (ULONG) IOBuffer[7];
files.checkdatetime = (ULONG) IOBuffer[12];
files.mode = (UWORD) IOBuffer[13];
files.checksize = (ULONG) IOBuffer[14];
}
AGLOBAL void files_loop(ULONG gid)
{ STRPTR stringptr;
switch (gid)
{
case GID_10_RA1:
if (!(GetAttr
( RADIOBUTTON_Selected, files_gadgets[GID_10_RA1], (ULONG *) &files.mode
)))
{ rq("Unsupported inquiry!"); // should never happen
}
files_updatelog();
break;
case GID_10_CB1:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB1], (ULONG *) &files.show[0]
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB2:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB2], (ULONG *) &(files.show[1])
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB3:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB3], (ULONG *) &files.show[2]
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB4:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB4], (ULONG *) &files.show[3]
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB5:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB5], (ULONG *) &files.checkversion
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB6:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB6], (ULONG *) &files.checkdatetime
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB7:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB7], &files.log
)))
{ rq("Unsupported inquiry!"); // should never happen
}
files_updatelog();
if (files.log)
{ ActivateLayoutGadget(files_gadgets[GID_10_LY1], MainWindowPtr, NULL, (Object) files_gadgets[GID_10_ST1]);
}
break;
case GID_10_CB8:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB8], (ULONG *) &files.checksize
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_ST1:
if (!(GetAttr
( STRINGA_TextVal, files_gadgets[GID_10_ST1], (ULONG *) &stringptr
)))
{ rq("Unsupported inquiry!"); // should never happen
}
strcpy(files.logfile, stringptr);
break;
case GID_10_ST2:
if (!(GetAttr
( STRINGA_TextVal, files_gadgets[GID_10_ST2], (ULONG *) &stringptr
)))
{ rq("Unsupported inquiry!"); // should never happen
}
strcpy(files.snapshot, stringptr);
break;
case GID_10_ST3:
if (!(GetAttr
( STRINGA_TextVal, files_gadgets[GID_10_ST3], (ULONG *) &stringptr
)))
{ rq("Unsupported inquiry!"); // should never happen
}
strcpy(files.basepath, stringptr);
addslash();
break;
case GID_10_BU1:
if (asl("#?.log"))
{ strcpy(files.logfile, aslresult);
SetGadgetAttrs
( files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
STRINGA_TextVal, files.logfile,
TAG_END
);
}
break;
case GID_10_BU2:
updatefiles();
break;
case GID_10_BU4:
if (asl("#?.snapshot"))
{ strcpy(files.snapshot, aslresult);
SetGadgetAttrs
( files_gadgets[GID_10_ST2], MainWindowPtr, NULL,
STRINGA_TextVal, files.snapshot,
TAG_END
);
}
break;
case GID_10_BU5:
if (dirasl())
{ strcpy(files.basepath, aslresult);
SetGadgetAttrs
( files_gadgets[GID_10_ST3], MainWindowPtr, NULL,
STRINGA_TextVal, files.basepath,
TAG_END
);
addslash();
}
break;
default:
break;
} }
AGLOBAL ULONG Hook10Func(struct Hook *h, VOID *o, VOID *msg)
{ /* "When the hook is called, the data argument points to the
window object and message argument to the IntuiMessage." */
UWORD code, qual;
ULONG scroll = 0;
geta4(); // wait till here before doing anything
code = ((struct IntuiMessage *) msg)->Code;
qual = ((struct IntuiMessage *) msg)->Qualifier;
switch(code)
{
case SCAN_HELP:
if (status == STATUS_READY)
{ helpabout();
}
break;
case SCAN_ESCAPE:
if (status == STATUS_READY)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ cleanexit(EXIT_SUCCESS);
} else page = 0;
} else
{ assert(status == STATUS_BUSY);
status = STATUS_STOPPING;
}
break;
case SCAN_PERIOD:
if (asl("#?.log"))
{ strcpy(files.logfile, aslresult);
SetGadgetAttrs
( files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
STRINGA_TextVal, files.logfile,
TAG_END
);
}
break;
case SCAN_E:
if (files.mode == 0)
{ files.mode = 1;
} else
{ files.mode = 0;
}
SetGadgetAttrs
( files_gadgets[GID_10_RA1], MainWindowPtr, NULL,
RADIOBUTTON_Selected, files.mode,
TAG_END);
// we must explicitly refresh
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_RA1], MainWindowPtr, NULL);
files_updatelog();
break;
case SCAN_S:
ActivateLayoutGadget(files_gadgets[GID_10_LY1], MainWindowPtr, NULL, (Object) files_gadgets[GID_10_ST2]);
break;
case SCAN_B:
ActivateLayoutGadget(files_gadgets[GID_10_LY1], MainWindowPtr, NULL, (Object) files_gadgets[GID_10_ST3]);
break;
case SCAN_UP:
if (qual & IEQUALIFIER_CONTROL)
{ scroll = LBP_TOP;
} elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
{ scroll = LBP_PAGEUP;
} else scroll = LBP_LINEUP;
break;
case SCAN_DOWN:
if (qual & IEQUALIFIER_CONTROL)
{ scroll = LBP_BOTTOM;
} elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
{ scroll = LBP_PAGEDOWN;
} else scroll = LBP_LINEDOWN;
break;
default:
break;
}
if (code == SCAN_UP || code == SCAN_DOWN)
{ SetGadgetAttrs
( files_gadgets[GID_10_LB1], // pointer to gadget
MainWindowPtr, // pointer to window (not window object!)
NULL, // pointer to requester
LISTBROWSER_Position, scroll, // tags
TAG_DONE // done
);
}
return(1);
}
MODULE void stopping(STRPTR status)
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
GA_Text, status,
TAG_END
);
SetGadgetAttrs // `Stop'
( files_gadgets[GID_10_BU3], MainWindowPtr, NULL,
GA_Disabled, TRUE,
TAG_END
);
}
MODULE void files_updatelog(void)
{ ULONG i;
updateghosting();
SetGadgetAttrs // `Log to file:' (string)
( files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
GA_Disabled, innerghost,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_ST1], MainWindowPtr, NULL);
SetGadgetAttrs // `Log to file:' (ASL button)
( files_gadgets[GID_10_BU1], MainWindowPtr, NULL,
GA_Disabled, innerghost,
TAG_END
);
// buttons can autorefresh
SetGadgetAttrs
( files_gadgets[GID_10_CB5], MainWindowPtr, NULL,
GA_Disabled, outerghost,
TAG_END);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB5], MainWindowPtr, NULL);
SetGadgetAttrs
( files_gadgets[GID_10_CB6], MainWindowPtr, NULL,
GA_Disabled, outerghost,
TAG_END);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB6], MainWindowPtr, NULL);
SetGadgetAttrs
( files_gadgets[GID_10_CB7], MainWindowPtr, NULL,
GA_Disabled, outerghost,
TAG_END);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB7], MainWindowPtr, NULL);
SetGadgetAttrs
( files_gadgets[GID_10_CB8], MainWindowPtr, NULL,
GA_Disabled, outerghost,
TAG_END);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB8], MainWindowPtr, NULL);
for (i = 0; i <= 3; i++)
{ SetGadgetAttrs
( files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL,
GA_Disabled, outerghost,
TAG_END);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL);
} }
MODULE void updateghosting(void)
{ /* Decides whether certain gadgets should be ghosted or not, and
sets variables accordingly. */
if (files.mode == FILESMODE_COMPARE)
{ outerghost = FALSE;
if (files.log)
{ innerghost = FALSE;
} else
{ innerghost = TRUE;
} }
else
{ assert(files.mode == FILESMODE_BUILD);
outerghost =
innerghost = TRUE;
} }
MODULE void gadgetstate(ABOOL starting)
{ /* If starting is TRUE, we are starting the operation.
If starting is FALSE, we are ending the operation. */
BOOL innerstate, outerstate, inverse;
ULONG i;
if (starting)
{ innerstate =
outerstate = starting;
inverse = FALSE;
} else
{ innerstate = innerghost;
outerstate = outerghost;
inverse = TRUE;
}
// Disabled during operation, enabled otherwise ----------------------
SetGadgetAttrs // `Update'
( files_gadgets[GID_10_BU2], MainWindowPtr, NULL,
GA_Disabled, starting,
TAG_END
);
// buttons can autorefresh
SetGadgetAttrs
( files_gadgets[GID_10_ST2], MainWindowPtr, NULL,
GA_Disabled, starting,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_ST2], MainWindowPtr, NULL);
SetGadgetAttrs
( files_gadgets[GID_10_ST3], MainWindowPtr, NULL,
GA_Disabled, starting,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_ST3], MainWindowPtr, NULL);
SetGadgetAttrs
( files_gadgets[GID_10_BU4], MainWindowPtr, NULL,
GA_Disabled, starting,
TAG_END
);
// buttons can autorefresh
SetGadgetAttrs
( files_gadgets[GID_10_BU5], MainWindowPtr, NULL,
GA_Disabled, starting,
TAG_END
);
// buttons can autorefresh
/* This should work but seems not to :-(
SetGadgetAttrs
( files_gadgets[GID_10_RA1], MainWindowPtr, NULL,
GA_Disabled, starting,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_RA1], MainWindowPtr, NULL); */
// Enabled during operation, disabled otherwise ----------------------
SetGadgetAttrs // `Stop'
( files_gadgets[GID_10_BU3], MainWindowPtr, NULL,
GA_Disabled, inverse,
TAG_END
);
// buttons can autorefresh
// Disabled during operation and/or in build-mode --------------------
for (i = 0; i <= 3; i++)
{ SetGadgetAttrs
( files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL,
GA_Disabled, outerstate,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL);
}
SetGadgetAttrs
( files_gadgets[GID_10_CB5], MainWindowPtr, NULL,
GA_Disabled, outerstate,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB5], MainWindowPtr, NULL);
SetGadgetAttrs
( files_gadgets[GID_10_CB6], MainWindowPtr, NULL,
GA_Disabled, outerstate,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB6], MainWindowPtr, NULL);
SetGadgetAttrs
( files_gadgets[GID_10_CB7], MainWindowPtr, NULL,
GA_Disabled, outerstate,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB7], MainWindowPtr, NULL);
SetGadgetAttrs
( files_gadgets[GID_10_CB8], MainWindowPtr, NULL,
GA_Disabled, outerstate,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB8], MainWindowPtr, NULL);
// Disabled during operation and/or in build-mode and/or without
// logging -----------------------------------------------------------
SetGadgetAttrs // `Log to file:' (string)
( files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
GA_Disabled, innerstate,
TAG_END
);
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_ST1], MainWindowPtr, NULL);
SetGadgetAttrs // `Log to file:' (ASL button)
( files_gadgets[GID_10_BU1], MainWindowPtr, NULL,
GA_Disabled, innerstate,
TAG_END
);
// buttons can autorefresh
}
MODULE void AddFilesNode(struct List* ListPtr, STRPTR pathname, STRPTR datetime, STRPTR version, STRPTR size)
{ struct FilesNode* FilesNodePtr;
ULONG needed;
needed = sizeof(struct FilesNode) + strlen(pathname);
if (!(FilesNodePtr = AllocVec(needed, MEMF_CLEAR | MEMF_PUBLIC)))
{ rq("Out of memory!");
}
strcpy(FilesNodePtr->pathname, pathname);
strcpy(FilesNodePtr->datetime, datetime);
strcpy(FilesNodePtr->version, version );
strcpy(FilesNodePtr->size, size );
FilesNodePtr->matched = FALSE;
FilesNodePtr->Node.ln_Name = NULL;
FilesNodePtr->Node.ln_Type = NT_USER;
FilesNodePtr->Node.ln_Pri = 0;
AddTail((struct List *) ListPtr, (struct Node *) FilesNodePtr);
}
MODULE void FreeFilesNodes(struct List* ListPtr)
{ /* RKM Libraries, p. 496:
"Free the entire list, including the header. The header is not
updated as the list is freed. This function demonstrates how to
avoid referencing freed memory when deallocating nodes." */
struct FilesNode *WorkNodePtr, *NextNodePtr;
WorkNodePtr = (struct FilesNode *) (ListPtr->lh_Head); /* first node */
while (NextNodePtr = (struct FilesNode *) (WorkNodePtr->Node.ln_Succ))
{ FreeVec(WorkNodePtr);
WorkNodePtr = NextNodePtr;
}
NewList(ListPtr);
}
MODULE void addslash(void)
{ ULONG length;
length = strlen(files.basepath);
if (length)
{ if
( files.basepath[length - 1] != '/'
&& files.basepath[length - 1] != ':'
)
{ strcat(files.basepath, "/");
SetGadgetAttrs
( files_gadgets[GID_10_ST3], MainWindowPtr, NULL,
STRINGA_TextVal, files.basepath,
TAG_END
);
} } }